﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.OleDb;

namespace Comercia
{
    public partial class form : Form
    {
        OleDbConnection conexion = null;

        public form()
        {
            InitializeComponent();
            VaciarFormulario();
        }

        private void btnIngresar_Click(object sender, EventArgs e)
        {
            try
            {
                lblError.Text = "";

                noVacio("Identificador", txtIdentificador.Text);
                numericoValido("Identificador", txtIdentificador.Text, 4);
                identificadorValido(txtIdentificador.Text);
                int identificador = int.Parse(txtIdentificador.Text);

                stringValido("Nombre", txtNombre.Text, 10);
                string nombre = string.IsNullOrEmpty(txtNombre.Text) ? "" : txtNombre.Text.Trim();

                stringValido("Descripción", rchDescripcion.Text, 10);
                string descripcion = string.IsNullOrEmpty(rchDescripcion.Text) ? "" : rchDescripcion.Text.Trim();

                int precio = numericoValido("Precio", txtPrecio.Text, 5);
                int desuentos = porcentajeValido(txtDescuentos.Text);
                int impuestos = numericoValido("Impuestos", txtImpuestos.Text, 3);

                if (cmbProdServicio.SelectedItem.ToString() == "Producto")
                {
                    double tamanio = doubleValido("Tamaño", txtTamanio.Text, 8);
                    int peso = numericoValidoRango("Peso", txtPeso.Text, 1000);
                    string color = btnColor.BackColor.ToString();
                    string empaque = rchEmpaque.Text;
                }

                DesHabilitarControles();
            }
            catch (Exception ex)
            {
                lblError.Text = ex.Message;
                lblError.ForeColor = Color.Red;
            }
        }

        private void DesHabilitarControles()
        {
            txtIdentificador.Enabled = false;
            txtNombre.Enabled = false;
            rchDescripcion.Enabled = false;
            txtPrecio.Enabled = false;
            txtDescuentos.Enabled = false;
            txtImpuestos.Enabled = false;
            cmbProdServicio.Enabled = false;
            txtTamanio.Enabled = false;
            txtPeso.Enabled = false;
            btnColor.Enabled = false;
            rchEmpaque.Enabled = false;

            btnIngresar.Visible = false;
            btnConfirmar.Visible = true;
            btnCancelar.Visible = true;
        }

        private void HabilitarControles()
        {
            txtIdentificador.Enabled = true;
            txtNombre.Enabled = true;
            rchDescripcion.Enabled = true;
            txtPrecio.Enabled = true;
            txtDescuentos.Enabled = true;
            txtImpuestos.Enabled = true;
            cmbProdServicio.Enabled = true;

            switch (cmbProdServicio.SelectedItem.ToString())
            {
                case "Producto":
                    {
                        txtTamanio.Enabled = true;
                        txtPeso.Enabled = true;
                        btnColor.Enabled = true;
                        rchEmpaque.Enabled = true;
                        break;
                    }
                case "Servicio":
                    {
                        txtTamanio.Enabled = false;
                        txtPeso.Enabled = false;
                        btnColor.Enabled = false;
                        rchEmpaque.Enabled = false;
                        break;
                    }
            }
            btnIngresar.Visible = true;
            btnConfirmar.Visible = false;
            btnCancelar.Visible = false;
        }


        #region Validations
        private int numericoValidoRango(string field, string value, int maxValue)
        {
            int resultado = 0;

            if (string.IsNullOrEmpty(value))
                return 0;

            if (string.IsNullOrEmpty(value.Trim()))
                return 0;

            if (int.TryParse(value, out resultado))
            {
                if (resultado > maxValue)
                {
                    throw new Exception(field + " fuera de rango");
                }
                return resultado;
            }
            else
                throw new Exception(field + " no válido, debe ser numérico");
        }

        private bool stringValido(string field, string value, int maxLength)
        {
            if (!string.IsNullOrEmpty(value))
            {
                if (value.Trim().Length > maxLength)
                    throw new Exception(field + " excede tamaño permitido.");
            }
            return true;
        }

        private void noVacio(string field, string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                throw new Exception(field + " es campo obligatorio");
            }
            if (string.IsNullOrEmpty(value.Trim()))
            {
                throw new Exception(field + " es campo obligatorio");
            }
        }

        private bool identificadorValido(string field)
        {
            if (ConectarBase())
            {
                OleDbCommand cmd = conexion.CreateCommand();
                cmd.CommandText = "SELECT * FROM Producto P, Servicio S WHERE P.Identificacion = @ID or S.Identificacion = @ID";
                cmd.Parameters.Add("@ID", field.Trim());

                OleDbDataReader dr = cmd.ExecuteReader();

                bool ret = true;

                if (dr.Read())
                    throw new Exception("Identificador existente, ingrese otro");

                dr.Close();
                DesconectarBase();
                return ret;
            }
            else
                throw new Exception("Error de conexion a BD");
        }

        private int numericoValido(string field, string value, int maxLength)
        {
            int resultado = 0;

            if (string.IsNullOrEmpty(value))
                return 0;

            if (string.IsNullOrEmpty(value.Trim()))
                return 0;

            if (int.TryParse(value, out resultado))
            {
                if (resultado.ToString().Length > maxLength)
                {
                    throw new Exception(field + " fuera de rango");
                }
                return resultado;
            }
            else
                throw new Exception(field + " no válido, debe ser numérico");
        }

        private double doubleValido(string field, string value, int cantDecimales)
        {
            double resultado = 0;

            if (string.IsNullOrEmpty(value))
                return 0;

            if (string.IsNullOrEmpty(value.Trim()))
                return 0;

            if (double.TryParse(value, out resultado))
            {
                string[] numbers = value.Trim().Split(',');
                if (numbers.Length > 1)
                {
                    if (numbers[1].Length > cantDecimales)
                    {
                        throw new Exception(field + ", cantidad de decimales permitidos : " + cantDecimales);
                    }
                }
                return resultado;
            }
            else
                throw new Exception(field + " no válido, debe ser numérico");
        }


        private bool numericoNegativo(long value)
        {
            if (value < 0)
            {
                throw new Exception("Campo negativo");
            }
            return true;
        }

        private int porcentajeValido(string value)
        {
            int resultado = 0;

            if (string.IsNullOrEmpty(value))
                return 0;

            if (string.IsNullOrEmpty(value.Trim()))
                return 0;

            if (int.TryParse(value, out resultado))
            {
                if ((resultado < 0) || (resultado > 100))
                {
                    throw new Exception("Descuento no válido, debe estar en el rango 0 - 100");
                }
                else
                    return resultado;
            }
            else
                throw new Exception("Descuento no válido, debe ser numérico");
        }
        #endregion

        #region DataBase Functions
        private bool ConectarBase()
        {
            if (conexion == null)
            {
                conexion = new System.Data.OleDb.OleDbConnection();
                conexion.ConnectionString = Comercia.Default["ConnectionString"].ToString();
                conexion.Open();
            }
            return true;
        }

        private bool DesconectarBase()
        {
            if (conexion != null)
            {
                conexion.Close();
                conexion = null;
            }
            return true;
        }
        #endregion

        private bool AltaProducto(Producto prod)
        {
            if (ConectarBase())
            {
                OleDbCommand cmd = conexion.CreateCommand();
                cmd.CommandText = "INSERT INTO Producto VALUES (@Identificacion, @Nombre, @Descripcion, @Precio, @Descuento, @Impuesto, @Empaque, @Peso, @Color, @Tamanio)";
                cmd.Parameters.AddWithValue("@Identificacion", prod.Identificador);
                cmd.Parameters.AddWithValue("@Nombre", prod.Nombre);
                cmd.Parameters.AddWithValue("@Descripcion", prod.Descripcion);
                cmd.Parameters.AddWithValue("@Precio", prod.Precio);
                cmd.Parameters.AddWithValue("@Descuento", prod.Descuentos);
                cmd.Parameters.AddWithValue("@Impuesto", prod.Impuestos);
                cmd.Parameters.AddWithValue("@Empaque", prod.Empaque);
                cmd.Parameters.AddWithValue("@Peso", prod.Peso);
                cmd.Parameters.AddWithValue("@Color", prod.Color);
                cmd.Parameters.AddWithValue("@Tamanio", prod.tamanio);

                int result = cmd.ExecuteNonQuery();
                DesconectarBase();

                if (result != 1)
                    throw new Exception("Error al ingresar producto");
                else
                    return true;
            }
            else
                throw new Exception("Error de conexion a BD");
        }

        private bool AltaServicio(Servicio serv)
        {
            if (ConectarBase())
            {
                OleDbCommand cmd = conexion.CreateCommand();
                cmd.CommandText = "INSERT INTO Servicio VALUES (@Identificacion, @Nombre, @Descripcion, @Precio, @Descuento, @Impuesto)";
                cmd.Parameters.AddWithValue("@Identificacion", serv.Identificador);
                cmd.Parameters.AddWithValue("@Nombre", serv.Nombre);
                cmd.Parameters.AddWithValue("@Descripcion", serv.Descripcion);
                cmd.Parameters.AddWithValue("@Precio", serv.Precio);
                cmd.Parameters.AddWithValue("@Descuento", serv.Descuentos);
                cmd.Parameters.AddWithValue("@Impuesto", serv.Impuestos);

                int result = cmd.ExecuteNonQuery();
                DesconectarBase();

                if (result != 1)
                    throw new Exception("Error al ingresar servicio");
                else
                    return true;
            }
            else
                throw new Exception("Error de conexion a BD");
        }

        private void btnColor_Click(object sender, EventArgs e)
        {
            colorDialog1 = new ColorDialog();
            colorDialog1.AllowFullOpen = false;
            colorDialog1.AnyColor = true;
            colorDialog1.SolidColorOnly = false;
            colorDialog1.Color = Color.Red;

            if (colorDialog1.ShowDialog() == DialogResult.OK)
            {
                btnColor.BackColor = colorDialog1.Color;
            }
        }

        private void btnConfirmar_Click(object sender, EventArgs e)
        {
            try
            {
                noVacio("Identificador", txtIdentificador.Text);
                numericoValido("Identificador", txtIdentificador.Text, 4);
                identificadorValido(txtIdentificador.Text);
                int identificador = int.Parse(txtIdentificador.Text);

                stringValido("Nombre", txtNombre.Text, 10);
                string nombre = string.IsNullOrEmpty(txtNombre.Text) ? "" : txtNombre.Text.Trim();

                stringValido("Descripción", rchDescripcion.Text, 10);
                string descripcion = string.IsNullOrEmpty(rchDescripcion.Text) ? "" : rchDescripcion.Text.Trim();

                int precio = numericoValido("Precio", txtPrecio.Text, 5);
                int desuentos = porcentajeValido(txtDescuentos.Text);
                int impuestos = numericoValido("Impuestos", txtImpuestos.Text, 3);


                switch (cmbProdServicio.SelectedItem.ToString())
                {
                    case "Producto":
                        {
                            double tamanio = doubleValido("Tamaño", txtPeso.Text, 8);
                            int peso = numericoValidoRango("Peso", txtPeso.Text, 1000);
                            string color = btnColor.BackColor.ToString();
                            string empaque = rchEmpaque.Text;

                            Producto prod = new Producto();
                            prod.Identificador = identificador;
                            prod.Nombre = nombre;
                            prod.Descripcion = descripcion;
                            prod.Precio = precio;
                            prod.Descuentos = desuentos;
                            prod.Impuestos = impuestos;
                            prod.Empaque = empaque;
                            prod.Peso = peso;
                            prod.Color = color;
                            prod.tamanio = tamanio;

                            AltaProducto(prod);
                            break;
                        }
                    case "Servicio":
                        {
                            Servicio serv = new Servicio();
                            serv.Identificador = identificador;
                            serv.Nombre = nombre;
                            serv.Descripcion = descripcion;
                            serv.Precio = precio;
                            serv.Descuentos = desuentos;
                            serv.Impuestos = impuestos;

                            AltaServicio(serv);
                            break;
                        }
                }

                lblError.Text = cmbProdServicio.SelectedItem.ToString() + " ingresado";
                lblError.ForeColor = Color.Green;

                VaciarFormulario();
                HabilitarControles();
            }
            catch (Exception ex)
            {
                lblError.Text = ex.Message;
                lblError.ForeColor = Color.Red;
            }
        }

        private void VaciarFormulario()
        {
            txtIdentificador.Text = string.Empty;
            txtNombre.Text = string.Empty;
            rchDescripcion.Text = string.Empty;
            txtPrecio.Text = string.Empty;
            txtDescuentos.Text = string.Empty;
            txtImpuestos.Text = string.Empty;
            cmbProdServicio.SelectedItem = "Servicio";

            txtTamanio.Text = string.Empty;
            txtTamanio.Enabled = false;

            txtPeso.Text = string.Empty;
            txtPeso.Enabled = false;

            btnColor.Enabled = false;
            btnColor.BackColor = Color.White;

            rchEmpaque.Text = string.Empty;
            rchEmpaque.Enabled = false;
        }

        private void btnCancelar_Click(object sender, EventArgs e)
        {
            HabilitarControles();
        }

        private void cmbProdServicio_SelectedValueChanged(object sender, EventArgs e)
        {
            switch (cmbProdServicio.SelectedItem.ToString())
            {
                case "Producto":
                    {
                        txtTamanio.Enabled = true;
                        txtPeso.Enabled = true;
                        btnColor.Enabled = true;
                        rchEmpaque.Enabled = true;
                        break;
                    }
                case "Servicio":
                    {
                        txtTamanio.Text = string.Empty;
                        txtTamanio.Enabled = false;

                        txtPeso.Text = string.Empty;
                        txtPeso.Enabled = false;

                        btnColor.Enabled = false;
                        btnColor.BackColor = Color.White;

                        rchEmpaque.Text = string.Empty;
                        rchEmpaque.Enabled = false;
                        break;
                    }
            }
        }
    }
}
